package com.luo.sc.oidc.authserver.handler.kapatcha.config;

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.luo.sc.oidc.authserver.controller.kaptcha.CaptchaController;
import com.luo.sc.oidc.authserver.handler.kapatcha.DefaultKaptchaResultSaveServiceImpl;
import com.luo.sc.oidc.authserver.handler.kapatcha.DelegatingKapatchaProducer;
import com.luo.sc.oidc.authserver.handler.kapatcha.KapatchResultSaveService;
import com.luo.sc.oidc.authserver.handler.kapatcha.UniLoginUserDetailsKaptchaMatcherService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.lang.Nullable;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * 谷歌验证码配置文件
 *
 * @author luohq
 * @version 1.0.0
 * @date 2022-03-04
 */
@ConditionalOnProperty(name = "spring.security.oauth2.authserver.enable-captcha", havingValue = "true")
@EnableConfigurationProperties(KaptchaConfigProps.class)
@ComponentScan(basePackageClasses = CaptchaController.class)
public class KaptchaConfig {

    /**
     * Kaptcha配置属性
     */
    private KaptchaConfigProps kaptchaConfigProps;

    public KaptchaConfig(KaptchaConfigProps kaptchaConfigProps) {
        this.kaptchaConfigProps = kaptchaConfigProps;
    }

    /**
     * 字符验证码生成器
     */
    @Bean
    public DefaultKaptcha kaptchaTextProducer() {
        DefaultKaptcha kaptchatextPropcer = new DefaultKaptcha();
        kaptchatextPropcer.setConfig(this.kaptchaConfigProps.getKaptchaTextConfig());
        return kaptchatextPropcer;
    }

    /**
     * 算术表达式验证码生成器
     */
    @Bean
    public DefaultKaptcha kaptchaMathProducer() {
        DefaultKaptcha kaptchaMathProducer = new DefaultKaptcha();
        kaptchaMathProducer.setConfig(this.kaptchaConfigProps.getKaptchaMathConfig());
        return kaptchaMathProducer;
    }

    /**
     * 定义默认的验证码保存服务实现（基于session）
     */
    @Bean
    @ConditionalOnMissingBean
    public KapatchResultSaveService kapatchResultSaveService() {
        return new DefaultKaptchaResultSaveServiceImpl();
    }

    /**
     * Kaptcha代理对象
     */
    @Bean
    public DelegatingKapatchaProducer delegatingKapatchaProducer(@Nullable KapatchResultSaveService kapatchResultSaveService) {
        return new DelegatingKapatchaProducer(this.kaptchaTextProducer(), this.kaptchaMathProducer(), kapatchResultSaveService);
    }

    /**
     * 定义统一用户查询及验证（支持图片验证码）服务
     *
     * @param userDetailsService
     * @param passwordEncoder
     * @return
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(name = "spring.security.oauth2.authserver.enable-captcha", havingValue = "true", matchIfMissing = false)
    UniLoginUserDetailsKaptchaMatcherService uniLoginUserDetailsKaptchaMatcherService(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder, DelegatingKapatchaProducer delegatingKapatchaProducer) {
        return new UniLoginUserDetailsKaptchaMatcherService(userDetailsService, passwordEncoder, delegatingKapatchaProducer);
    }

}
